package cn.itsource.elasticsearch;

import cn.itsource.domain.Pet;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.action.get.GetRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequestBuilder;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.document.DocumentField;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

public class ESDemo {

    //1. 创建索引库，添加文档
    @Test
    public void creatIndex(){
        // 1. 获取客户端连接
        TransportClient client = ESClientUtil.getClient();
        // 2. 通过API 操作 使用带 prepare ，预编译的
        // String index, 索引库的名字

        for (int i = 0; i < 50; i++) {
            // String type， 类型 表名
            IndexRequestBuilder indexRequestBuilder = client.prepareIndex("pet", "pet");

            // setSource 保存是对象
            //Pet pet = new Pet(1L,"二哈",20,true);
            Map<String,Object> pet = new HashMap<>();
            pet.put("id",i);
            pet.put("name",i%3==0?"二哈 "+i:"柯基 "+i);
            pet.put("age",20+i);
            pet.put("sex",i%2==0?1:0);
            IndexResponse response = indexRequestBuilder.setSource(pet).get();

            System.out.println(response);
        }
        // 3. 释放资源
        client.close();
    }

    //2.查询
    @Test
    public void search() {
        // 1. 获取客户端连接
        TransportClient client = ESClientUtil.getClient();
        // String index, String type, String id
        GetResponse documentFields = client.prepareGet("pet", "pet", "1").get();

        // getSource() 只查询数据
        System.out.println(documentFields.getSource());

    }

    //23修改
    @Test
    public void update() {
        // 1. 获取客户端连接
        TransportClient client = ESClientUtil.getClient();

        UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate("pet", "pet", "1");

        Map<String,Object> pet = new HashMap<>();
        pet.put("id",1L);
        pet.put("sex",0);
        // 增量的修改
        UpdateResponse updateResponse = updateRequestBuilder.setDoc(pet).get();
        System.out.println(updateResponse);

        client.close();

    }

    // 4. 删除
    @Test
    public void delet() {
        // 1. 获取客户端连接
        TransportClient client = ESClientUtil.getClient();
        client.prepareDelete("pet","pet","1").get();
        client.close();
    }


    // 5. 高级查询
    // 名称(name)中有 "zs" 的用户 ，性别sex是男生(1),年龄（age）在 18- 20之间,
    // 按照年龄（age）倒排序，查询第 1 页，每页10 条
    @Test
    public void advancedSearch() {
        // 1. 获取客户端连接
        TransportClient client = ESClientUtil.getClient();

        // 获取查询构造器
        SearchRequestBuilder searchRequestBuilder = client.prepareSearch("pet");
        // 排序
        searchRequestBuilder.addSort(new FieldSortBuilder("age").order(SortOrder.DESC));
        searchRequestBuilder.setFrom(0).setSize(10);

        // 组合
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 名称(name)中有 "二哈" 的用户
        boolQueryBuilder.must(QueryBuilders.matchQuery("name","二哈"));

        // 性别sex是男生(1)
        boolQueryBuilder.filter(QueryBuilders.termQuery("sex", "1"));
        // 年龄（age）在 18- 20之间
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gte(20).lte(30));

        // 绑定查询条件，get 获得响应的数据，查询结果
        SearchResponse response = searchRequestBuilder.setQuery(boolQueryBuilder).get();// 添加查询条件
        System.out.println("response: "+response);
        SearchHits hits = response.getHits();
        System.out.println("命中："+hits.totalHits);
        // 查询到的文档
        SearchHit[] documents = hits.getHits();
        for (SearchHit document : documents) {
            System.out.println(document.getSourceAsMap());
        }
    }
}
